import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Stack;

import static com.sun.deploy.trace.Trace.flush;
//ceshiyong
/**
 * Created by Administrator on 2016/6/6 0006.
 */
public class MazeJFrame extends JFrame{
    /*************** 外部接口数据 ***************/
    private MazeFaceJPanel mazeFaceJPanel;
    private Maze maze;

    /*************** 内部数据 ***************/
    /* 第一个页面 */
    private int mazeFirstHight = 160;
    private int mazeFirstWidth = 234;
    private JTextField  jTMazeWidth;
    private JLabel      jLMazeWidth;
    private JTextField  jTMazeHight;
    private JLabel      jLMazeHight;
    private JButton     jBMazeGenerat;
    private JPanel      JPFirstPanel;

    /* 第二个页面 */
    private int mazeSecondHigh = 456;
    private int mazeSecondWidth = 456;
    private JTextField  JTGeneratNewThreadRate;
    private JLabel      JLGeneratNewThreadRate;
    private JComboBox   JCBNewThreadRate;
    private JTextField  JTMaxStep;
    private JLabel      JLMaxSetp;
    private JTextField  JTGeneratPathRate;
    private JLabel      JLGeneratPathRate;
    private JButton  JBMazeStart;
    private JButton     JBBack;
    private JPanel      JPSecondPanel;
    private JPanel      JPUpControl;
    private JPanel      JPDownControl;
    private JPanel      JPControl;

    public static void main(String[] args){
        MazeJFrame mazeJFrame = new MazeJFrame();
    }
    public MazeJFrame(){
        /* 第一个页面 */
        jTMazeWidth = new JTextField(8);
        jLMazeWidth = new JLabel("迷宫宽度");
        jTMazeHight = new JTextField(8);
        jLMazeHight = new JLabel("迷宫高度");
        jBMazeGenerat = new JButton("生成迷宫");
        JPFirstPanel = new JPanel();
        jBMazeGenerat.addActionListener(new MyButtonActionListener());


        /* 第二个页面 */
        JTGeneratNewThreadRate = new JTextField(8);
        JLGeneratNewThreadRate = new JLabel("线程生成率");
        JTGeneratPathRate = new JTextField(8);
        JLGeneratPathRate = new JLabel("速度（毫秒）");
        JTMaxStep = new JTextField(8);
        JLMaxSetp = new JLabel("最大步数");
        JBMazeStart = new JButton("启动迷宫");
        JBBack      = new JButton("返回");
        JCBNewThreadRate = new JComboBox();
        JPSecondPanel = new JPanel();
        JPUpControl = new JPanel();
        JPDownControl = new JPanel();
        JPControl = new JPanel();
        JBMazeStart.addActionListener(new MyButtonActionListener());
        JBBack.addActionListener(new MyButtonActionListener());
        maze = new Maze(this);
        mazeFaceJPanel = new MazeFaceJPanel(maze);

        setFirstPage();
        setSecondPage();
        addFirstPage();

        setPageLocation(mazeFirstWidth, mazeFirstHight);
        setSize(mazeFirstWidth, mazeFirstHight);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setTitle("迷宫生成");
        setVisible(true);
    }
    public MazeFaceJPanel getMazeFaceJPanel(){
        return mazeFaceJPanel;
    }
    public JComboBox getJCBNewThreadRate(){
        return JCBNewThreadRate;
    }
    public JTextField getJTMaxStep(){
        return JTMaxStep;
    }
    public JTextField getJTGeneratPathRate(){
        return JTGeneratPathRate;
    }
    public JButton getJBMazeStart(){
        return JBMazeStart;
    }
    public void setPageLocation(int width, int height){
        Dimension   screensize   =   Toolkit.getDefaultToolkit().getScreenSize();
        int screeWid = (int)screensize.getWidth();
        int screeHig = (int)screensize.getHeight();
        setLocation((screeWid - width)/2, (screeHig - height)/2);
    }
    /* 设置页面二的大小 */
    public void setSecondPageSize(){
        int secondWidth = (Integer.parseInt(jTMazeWidth.getText()))*(mazeFaceJPanel.pointWidth + mazeFaceJPanel.mazeFrameWidth)+260;
        int secondHigh = (Integer.parseInt(jTMazeHight.getText()))*(mazeFaceJPanel.pointHeigh + mazeFaceJPanel.mazeFrameHeight)+80;
        if(secondHigh < 200){
            secondHigh = 200;
        }
        mazeSecondWidth = secondWidth;
        mazeSecondHigh = secondHigh;
        setSize(mazeSecondWidth, mazeSecondHigh);
        setPageLocation(mazeSecondWidth, mazeSecondHigh);
        mazeFaceJPanel.setMazeFace(mazeSecondWidth,mazeSecondHigh);
    }
    /* 设置页面一的大小 */
    public void setFirstPageSize(){
        setSize(mazeFirstWidth, mazeFirstHight);
        setPageLocation(mazeFirstWidth, mazeFirstHight);
        mazeFaceJPanel.setMazeFace(mazeFirstWidth,mazeFirstHight);
    }
    /* 添加页面一 */
    public void setFirstPage(){
        JPFirstPanel.setLayout(new FlowLayout());
        JPFirstPanel.setPreferredSize(new Dimension(200,0));
        JPFirstPanel.add(jTMazeWidth);
        JPFirstPanel.add(jLMazeWidth);
        JPFirstPanel.add(jTMazeHight);
        JPFirstPanel.add(jLMazeHight);
        JPFirstPanel.add(jBMazeGenerat);
    }
    /* 设置页面二 */
    public void setSecondPage(){
        JPUpControl.setLayout(new GridLayout(4,2,1,1));
        for(int i = 0; i <= 9;i++){
            JCBNewThreadRate.addItem("0."+i);
        }
        JCBNewThreadRate.setSelectedIndex(1);
        //JPUpControl.setBackground(Color.green);
        JPUpControl.add(new JLabel(""));
        JPUpControl.add(new JLabel(""));
        JPUpControl.add(JCBNewThreadRate);
        JPUpControl.add(JLGeneratNewThreadRate);
        JPUpControl.add(JTMaxStep);
        JPUpControl.add(JLMaxSetp);
        JPUpControl.add(JTGeneratPathRate);
        JPUpControl.add(JLGeneratPathRate);


        JPDownControl.setLayout(new GridLayout(2,2,1,1));
        JPDownControl.add(JBMazeStart);
        JPDownControl.add(JBBack);
        JPDownControl.add(new JLabel());
        JPDownControl.add(new JLabel());

        JPControl.setLayout(new BorderLayout());
        //JPControl.setBackground(Color.blue);
        JPControl.setPreferredSize(new Dimension(200,0));
        JPControl.add(JPUpControl, BorderLayout.NORTH);
        JPControl.add(JPDownControl, BorderLayout.SOUTH);

        JPSecondPanel.setLayout(new BorderLayout());
        JPSecondPanel.add(JPControl,BorderLayout.WEST);
        JPSecondPanel.add(mazeFaceJPanel,BorderLayout.CENTER);
    }
    /* 切换到页面二 */
    public void changeToSecond(){
        if(!judgeJPanelDataValid(jTMazeWidth, jTMazeHight)){
            return;
        }
        maze.setHighAndWidth(Integer.parseInt(jTMazeWidth.getText()), Integer.parseInt(jTMazeHight.getText()));
        addSecondePage();
        setSecondPageSize();
    }
    /* 数据合法性判断 */
    public boolean judgeJPanelDataValid(JTextField jtMazeWidth, JTextField jtMazeHight){
        String strMazeWidth = jTMazeWidth.getText();
        String strMazeHeight = jTMazeHight.getText();
        int mazeWidth,mazeHeight;
        if(strMazeWidth.isEmpty() || strMazeHeight.isEmpty()){
            JOptionPane.showMessageDialog(null,
                    "长度或宽度不可为空", "警告", JOptionPane.INFORMATION_MESSAGE);
            return false;
        }
        try {
            mazeWidth = Integer.parseInt(strMazeWidth);
            mazeHeight = Integer.parseInt(strMazeHeight);
        }catch(NumberFormatException e){
            JOptionPane.showMessageDialog(null,
                    "长度或者宽度不可为非数字", "警告", JOptionPane.INFORMATION_MESSAGE);
            return false;
        }
        if(mazeWidth > 80 || mazeHeight > 40){
            JOptionPane.showMessageDialog(null,
                    "长度最大80，宽度最大40，请正确填写", "警告", JOptionPane.INFORMATION_MESSAGE);
            return false;
        }
        return true;
    }
    /* 切换到页面一 */
    public void changeToFirst(){
        addFirstPage();
        maze.setHighAndWidth(mazeFirstWidth, mazeFirstHight);

        setFirstPageSize();
        maze.dataClear();
    }
    /* 显示页面一 */
    public void addFirstPage(){
        this.remove(JPSecondPanel);
        this.add(JPFirstPanel);
    }
    /* 显示页面二 */
    public void addSecondePage(){
        this.remove(JPFirstPanel);
        this.add(JPSecondPanel);
    }
    public class MyButtonActionListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if(e.getActionCommand() == "生成迷宫"){
                changeToSecond();
            }
            else if(e.getActionCommand() == "启动迷宫"){
                System.out.println("启动迷宫");
                maze.mazeStart(MazeJFrame.this);
            }
            else if(e.getActionCommand() == "返回"){
                changeToFirst();
                //maze.getMazeAlgorithm().mazeStop();
                //maze.drawTest();
                maze.mazeStop();
            }
            else if(e.getActionCommand() == "停止"){
                System.out.println("停止");
                maze.mazeStop();
            }
        }
    }

}
class MazeFaceJPanel extends JPanel {
    /*************** 外部接口数据 ***************/
    private MazePoint stepedPoint;
    private Maze maze;

    /*************** 内部数据 ***************/
    public static final int mazeFaceHeightOffset = 20;
    public static final int mazeFaceWidthOffset = 20;
    public static final int pointHeigh = 10;
    public static final int pointWidth = 10;
    public static final int mazeFrameHeight = 4;
    public static final int mazeFrameWidth = 4;
    public static final boolean draw3dFlag = false;   //表示当前是否采用3D

    public MazeFaceJPanel(Maze m){
        stepedPoint = new MazePoint(6,9);
        maze = m;
    }
    public void setMazeFace(int width, int heigh) {
        this.setSize(width*(pointWidth+mazeFrameWidth) + 3*pointWidth, heigh*(pointHeigh+mazeFrameHeight) +3*pointHeigh);
        repaint();
    }
    /* 刷新屏幕 */
    public synchronized void refresh(){
        repaint();
    }
    /* 画主界面 */
    public synchronized void drawMazeFace(Graphics g){
        for(int heighIdx = 0;heighIdx < maze.getMazeAlgorithm().getMazeHight(); heighIdx++){
            for(int widthIdx = 0; widthIdx < maze.getMazeAlgorithm().getMazeWidth(); widthIdx++){
                drawFaceMiddle(g,maze.getMazeAlgorithm().getMazePoints()[widthIdx][heighIdx]);
            }
        }
    }
    /* 画迷宫边框*/
    public synchronized void drawMazeFrame(Graphics g){
//        if(maze.getMazeAlgorithm().getmazeNoteNum() == 0){
//            return;
//        }
        /* 画迷宫的点还有左和上边框 */
        for(int heighIdx = 0;heighIdx < maze.getMazeAlgorithm().getMazeHight(); heighIdx++) {//y
            for (int widthIdx = 0; widthIdx < maze.getMazeAlgorithm().getMazeWidth(); widthIdx++) {//x
                drawFacePoint(g,maze.getMazeAlgorithm().getMazePoints()[widthIdx][heighIdx]);
                drawFaceFrame(g,maze.getMazeAlgorithm().getMazePoints()[widthIdx][heighIdx], MazeDirection.LEFT);
                drawFaceFrame(g,maze.getMazeAlgorithm().getMazePoints()[widthIdx][heighIdx], MazeDirection.UP);
            }
        }
        /* 画迷宫右边的点和边框 */
        int rightFrameWidth = maze.getMazeAlgorithm().getMazeWidth();
        MazePoint rightMazeFramePoint = new MazePoint();
        rightMazeFramePoint.setMazeX(rightFrameWidth);
        for(int heighIdx = 0;heighIdx < maze.getMazeAlgorithm().getMazeHight(); heighIdx++) {
            rightMazeFramePoint.setMazeY(heighIdx);
            /*画点*/
            drawFacePoint(g,rightMazeFramePoint);
            if(rightMazeFramePoint.equalsPoint(maze.getMazeAlgorithm().getMazeEndPoint())){
                drawFaceFrame(g,maze.getMazeAlgorithm().getMazeEndPoint(), MazeDirection.LEFT);
            }
            else {
                drawFaceFrame(g, rightMazeFramePoint, MazeDirection.LEFT);
            }
        }
        /* 画迷宫下边的点和边框 */
        int downFrameHeigh = maze.getMazeAlgorithm().getMazeHight();
        MazePoint downMazeFramePoint = new MazePoint();
        downMazeFramePoint.setMazeY(downFrameHeigh);
        for (int widthIdx = 0; widthIdx < maze.getMazeAlgorithm().getMazeWidth(); widthIdx++) {
            downMazeFramePoint.setMazeX(widthIdx);
            drawFacePoint(g,downMazeFramePoint);
            drawFaceFrame(g, downMazeFramePoint, MazeDirection.UP);
        }
        /* 画右下角的点 */
        drawFacePoint(g,new MazePoint(maze.getMazeAlgorithm().getMazeWidth(),maze.getMazeAlgorithm().getMazeHight()));
    }
    public void draw3DorNot(Graphics g, boolean draw3Dflag, int x, int y, int width, int heigh){
        if(draw3Dflag == true){
            g.fill3DRect(x,y,width,heigh,false);
        }
        else{
            g.fillRect(x,y,width,heigh);
        }
    }
    /*画点*/
    public void drawFacePoint(Graphics g, MazePoint mazePoint){
        setColor(g, false);
        draw3DorNot(g,draw3dFlag,mazeFaceWidthOffset + mazePoint.getMazeX()*(pointWidth + mazeFrameWidth),
                mazeFaceHeightOffset + mazePoint.getMazeY()*(pointHeigh + mazeFrameHeight),
                mazeFrameWidth,
                mazeFrameHeight);
    }
    /*画边框*/
    public void drawFaceFrame(Graphics g, MazePoint mazePoint, MazeDirection mazeDirection){
        boolean isSteped = false;
        switch (mazeDirection){
            case UP:
                setColor(g, mazePoint.getUpSteped());
                draw3DorNot(g,draw3dFlag,
                        mazeFaceWidthOffset + mazePoint.getMazeX()*(pointWidth + mazeFrameWidth) + mazeFrameWidth,
                        mazeFaceHeightOffset + mazePoint.getMazeY()*(pointHeigh + mazeFrameHeight),
                        pointWidth,
                        mazeFrameHeight);
                break;
            case LEFT:
                /* 判断当前是否是迷宫出口 */
                if(maze.getMazeAlgorithm().getMazeEndPoint().equalsPoint(mazePoint)){

                }
                setColor(g, mazePoint.getLeftSteped());
                draw3DorNot(g,draw3dFlag,
                        mazeFaceWidthOffset + mazePoint.getMazeX()*(pointWidth + mazeFrameWidth),
                        mazeFaceHeightOffset + mazePoint.getMazeY()*(pointHeigh + mazeFrameHeight) + mazeFrameHeight,
                        mazeFrameWidth,
                        pointHeigh);
                break;
            default:break;
        }
    }
    /*画中间*/
    public void drawFaceMiddle(Graphics g, MazePoint mazePoint){
        setFaceColor(g, mazePoint.getSteped());
        //g.setColor(Color.cyan);
        draw3DorNot(g,draw3dFlag,
                mazeFaceWidthOffset + mazeFrameWidth + mazePoint.getMazeX()*(pointWidth + mazeFrameWidth),
                mazeFaceHeightOffset + mazeFrameHeight + mazePoint.getMazeY()*(pointHeigh + mazeFrameHeight),
                pointWidth,
                pointHeigh);
    }
    public void setColor(Graphics g, boolean isSteped){
        if(isSteped == true){
            g.setColor(new Color(245, 246, 227));
        }
        else{
            g.setColor(new Color(246, 158, 70));
        }
    }
    public void setFaceColor(Graphics g, boolean isSteped){
        if(isSteped){
            g.setColor(new Color(245, 246, 227));
        }
        else{
            g.setColor(new Color(246, 158, 70));
            //g.setColor(new Color(179, 246, 30));
        }
    }

    public synchronized void paint(Graphics g){
        super.paint(g);
        //g.setColor(new Color(246, 158, 70));
        drawMazeFrame(g);
        drawMazeFace(g);
        //flush();
        //g.fillRect(width,height,10,10);
    }
}

